package com.mti.epivisitemobile.view
{
	import com.mti.epivisite.common.event.EventProxyBase;
	import com.mti.epivisite.common.event.Waypoint;
	import com.mti.epivisite.common.event.WaypointView;
	import com.mti.epivisite.common.map.MapImages;
	import com.mti.epivisite.common.map.MapProxyBase;
	import com.mti.epivisitemobile.Constants;
	import com.mti.epivisitemobile.model.EventListProxy;
	
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import media.MediaPoint;
	
	import mx.collections.ArrayCollection;
	import mx.core.FlexGlobals;
	import mx.events.FlexEvent;
	import mx.graphics.SolidColorStroke;
	
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;
	
	import spark.effects.Animate;
	import spark.effects.animation.MotionPath;
	import spark.effects.animation.SimpleMotionPath;
	import spark.primitives.Line;
	
	public class MapViewMediator extends Mediator
	{
		public static const NAME:String = "MapViewMediator";
		
		public function MapViewMediator(viewComponent:MapView)
		{
			super(NAME, viewComponent);
			
			view.addEventListener(FlexEvent.CREATION_COMPLETE, onViewCreationComplete);
		}
		
		private var _eventProxy:EventProxyBase = null;
		
		private function onViewCreationComplete(event:FlexEvent):void
		{
			view.removeEventListener(FlexEvent.CREATION_COMPLETE, onViewCreationComplete);
			
			_eventProxy = EventProxyBase(facade.retrieveProxy(EventProxyBase.NAME));
			
			if (_eventProxy.isLoaded == true)
				_eventProxy.getPoints(_eventProxy.baseEvent);
		}
		
		private var _selectedWaypoint:MediaPoint = null;
		private function set selectedWaypoint(value:MediaPoint):void
		{
			_selectedWaypoint = value;
			if (_selectedWaypoint == null)
			{
				view.setCurrentState("normal");
			}
			else
			{
				view.setCurrentState("poi");
				view.detailsButton.addEventListener(MouseEvent.CLICK, onDetailsButtonClick);
				view.visitedButton.addEventListener(MouseEvent.CLICK, onVisitedButtonClick);
			}
		}
		
		private function onPoiClick(event:MouseEvent):void
		{
			var img:WaypointView = WaypointView(event.currentTarget);
			selectedWaypoint = img.waypoint;
			
			view.visitedButton.label = (_selectedWaypoint.Visited == true) ? "Mark as unvisited" : "Mark as visited";
			
			FlexGlobals.topLevelApplication.viewMenuOpen = true;
		}
		
		private var routeTimer:Timer = null;
		
		private function onRouteButtonClick(event:MouseEvent):void
		{
			view.routeButton.enabled = false;
			
			routeTimer = new Timer(500, route.length + 1);
			routeTimer.addEventListener(TimerEvent.TIMER, onRouteTimerTick);
			routeTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onRouteTimerComplete);
			
			routeTimer.start();
		}
		
		private var toNextLine:Line = null;
		private var fromPrevLine:Line = null;
		
		private function onRouteTimerTick(event:TimerEvent):void
		{
			if (fromPrevLine != null)
				view.mapContainer.removeElement(fromPrevLine);
			fromPrevLine = toNextLine;
			
			if (routeTimer.currentCount == routeTimer.repeatCount)
				return;
			
			var wpIndex:int = routeTimer.currentCount - 1;
			var cur:MediaPoint = route[wpIndex];
			var anim:Animate = null;
			var motionPath:SimpleMotionPath = null;
			
			if (wpIndex > 0)
			{
				var prev:MediaPoint = route[wpIndex - 1];
				anim = new Animate(fromPrevLine);
				anim.motionPaths = new Vector.<MotionPath>();
				motionPath = new SimpleMotionPath("xFrom", prev.posX, cur.posX);
				anim.motionPaths.push(motionPath);
				motionPath = new SimpleMotionPath("yFrom", prev.posY, cur.posY);
				anim.motionPaths.push(motionPath);
				anim.duration = 500;
				anim.play();
			}
			
			if (wpIndex < (route.length - 1))
			{
				var next:MediaPoint = route[wpIndex + 1];
				toNextLine = new Line();
				//toNextLine.width = 2;
				toNextLine.xFrom = cur.posX;
				toNextLine.yFrom = cur.posY;
				view.mapContainer.addElement(toNextLine);
				toNextLine.stroke = new SolidColorStroke(0xff0000);
				anim = new Animate(toNextLine);
				anim.motionPaths = new Vector.<MotionPath>();
				motionPath = new SimpleMotionPath("xTo", cur.posX, next.posX);
				anim.motionPaths.push(motionPath);
				motionPath = new SimpleMotionPath("yTo", cur.posY, next.posY);
				anim.motionPaths.push(motionPath);
				anim.duration = 500;
				anim.play();
			}
		}								  
		
		private function onRouteTimerComplete(event:TimerEvent):void
		{
			routeTimer.removeEventListener(TimerEvent.TIMER, onRouteTimerTick);
			routeTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, onRouteTimerComplete);
			
			fromPrevLine = null;
			toNextLine = null;
			
			view.routeButton.enabled = true;
		}
		
		private function onDetailsButtonClick(event:MouseEvent):void
		{
			sendNotification(Constants.LOAD_POI, _selectedWaypoint.QRCode);
		}
		
		private function onVisitedButtonClick(event:MouseEvent):void
		{
			var visited:Boolean = !(_selectedWaypoint.Visited);
			_selectedWaypoint.Visited = visited;
			view.visitedButton.label = (visited == true) ? "Mark as unvisited" : "Mark as visited";
		}
		
		override public function listNotificationInterests():Array
		{
			return [
				EventProxyBase.LOAD_SUCCESS,
				EventProxyBase.GET_POINTS_SUCCESS
			];
		}
		
		override public function handleNotification(note:INotification):void
		{
			switch (note.getName())
			{
				case EventProxyBase.LOAD_SUCCESS:
					_eventProxy.getPoints(_eventProxy.baseEvent);
					break;
				case EventProxyBase.GET_POINTS_SUCCESS:
					onEventLoadSuccess();
					break;
			}
		}
		
		private var route:ArrayCollection = null;
		
		private function onEventLoadSuccess():void
		{
			view.mapImage.source = MapImages.Plan;
			
			var oldWp:MediaPoint = null;
			route = new ArrayCollection();
			for each (var wp:MediaPoint in _eventProxy.baseEvent.pointList)
			{
				if (wp.QRCode != null)
				{
					var wpView:WaypointView = new WaypointView();
					wpView.waypoint = wp;
					wpView.addEventListener(MouseEvent.CLICK, onPoiClick);
					view.mapContainer.addElement(wpView);
				}
				else
				{
					route.addItem(wp);
				}
				
				/*if (oldWp != null)
				{
					var line:Line = new Line();
					line.xFrom = oldWp.x;
					line.yFrom = oldWp.y;
					line.xTo = wp.x;
					line.yTo = wp.y;
					line.stroke = new SolidColorStroke();
					view.mapContainer.addElement(line);
					
					_line = line;
				}
				oldWp = wp;*/
			}
			
			view.routeButton.addEventListener(MouseEvent.CLICK, onRouteButtonClick);
		}
		
		private function get view():MapView
		{
			return viewComponent as MapView;
		}
	}
}